#ifndef UNIFIEDCACHEMANAGER_H
#define UNIFIEDCACHEMANAGER_H

#include <QObject>
#include <QString>
#include <QDir>
#include <QFileInfo>
#include <QDateTime>
#include <QList>
#include <QDebug>
#include <QMutex>
#include <QImage>
#include <QHash>
#include <QTimer>
#include <QStorageInfo>

/**
 * 统一的缓存管理类
 * 整合了原CacheManager和UnifiedCacheManager的功能
 * 提供完整的缓存管理功能，包括图片缓存、目录管理、清理等
 */
class UnifiedCacheManager : public QObject
{
    Q_OBJECT

public:
    // 单例模式
    static UnifiedCacheManager* instance();
    
    // 缓存目录管理
    QString getCacheDirectory() const;
    bool cacheDirectoryExists() const;
    void setCacheDirectory(const QString& dir);
    
    // 缓存条目管理
    struct CacheEntry {
        QString hash;           // 缓存目录名（文件标识符）
        QString fullPath;       // 完整路径
        int pageCount;          // 页面数量
        qint64 sizeBytes;       // 大小（字节）
        QDateTime lastModified; // 最后修改时间
        QString sourcePath;     // 源文件路径（从manifest.json读取）
        bool isValid;           // 是否为有效缓存
    };
    
    // 缓存项结构（用于内存管理）
    struct CacheItem {
        QString filePath;           // 缓存文件路径
        QDateTime createdTime;      // 创建时间
        QDateTime lastAccessTime;   // 最后访问时间
        int accessCount;            // 访问次数
        qint64 fileSize;           // 文件大小
        
        CacheItem() : accessCount(0), fileSize(0) {}
    };
    
    QList<CacheEntry> scanCacheEntries() const;
    qint64 getTotalCacheSize() const;
    int getCacheEntryCount() const;
    
    // 图片缓存操作
    bool saveToCache(const QString& fileIdentity, int pageIndex, const QImage& image, double dpi = 0.0);

    // === Martin Fowler重构：文件级缓存创建，自动记录缓存目录 ===
    /**
     * 保存图片到缓存，并记录实际缓存目录到文件信息中
     * @param fileInfo 文件信息对象，将被更新缓存路径信息
     * @param pageIndex 页面索引
     * @param image 要保存的图片
     * @param dpi DPI设置，用于保存到PNG文件中
     * @return 如果保存成功返回true
     */
    bool saveToCacheWithFileInfo(class UnifiedFileInfo& fileInfo, int pageIndex, const QImage& image, double dpi = 0.0);
    QImage loadFromCache(const QString& fileIdentity, int pageIndex);
    bool isCached(const QString& fileIdentity, int pageIndex);
    QList<QImage> loadAllThumbnails(const QString& fileIdentity, int totalPages);
    
    // 缓存清理操作
    void clearCache(const QString& originalPath = QString());
    void cleanupOldCache(int daysOld = 30);
    void cleanupBySize(qint64 maxSizeMB = 500);
    bool deleteCacheEntry(const QString& hash);
    bool deleteAllCache();
    bool deleteCacheEntries(const QStringList& hashes);
    bool clearFileCache(const QString& filePath); // 清除指定文件的缓存
    bool clearAllCache(); // 清除缓存目录里所有子目录和文件
    
    // 缓存信息查询
    bool isCacheEntryValid(const QString& hash) const;
    CacheEntry getCacheEntryInfo(const QString& hash) const;
    
    // 缓存统计信息
    qint64 getCacheSize() const;
    qint64 getActualCacheSize() const;
    qint64 getCachedActualSize() const;
    void refreshActualCacheSize() const;
    int getCacheCount() const;
    QHash<QString, QList<CacheItem>> getCacheInfo() const;
    
    // 文件标识和路径管理
    QString getFileIdentityForPath(const QString& originalPath) const;
    QString getCacheDirFor(const QString& originalPath) const;

    // === Martin Fowler重构：文件级缓存路径管理 ===
    /**
     * 获取文件的缓存目录（使用文件级路径信息）
     * @param fileInfo 文件信息对象，包含缓存路径信息
     * @return 文件的完整缓存目录路径
     */
    QString getCacheDirForFileInfo(const class UnifiedFileInfo& fileInfo) const;

    /**
     * 清除指定文件的缓存（使用文件级路径信息）
     * @param fileInfo 文件信息对象
     * @return 如果清除成功返回true
     */
    bool clearFileCacheWithFileInfo(const class UnifiedFileInfo& fileInfo);
    int getCachedPageCount(const QString& originalPath) const;
    QDateTime getCachedLatestTime(const QString& originalPath) const;
    bool cacheExistsWithPages(const QString& originalPath) const;
    
    // 配置管理
    void setMaxCacheSize(qint64 sizeMB);
    void setMaxCacheAge(int days);

    // 导出优化缓存
    struct ExportCacheEntry {
        QString filePath;
        QString exportHash;      // 导出设置的哈希值
        QString tempPdfPath;     // 临时PDF文件路径
        QDateTime createdTime;   // 创建时间
        qint64 fileSize;        // 文件大小
        bool isValid;           // 是否有效

        ExportCacheEntry() : fileSize(0), isValid(false) {}
    };

    // 导出缓存操作
    bool saveExportCache(const QString& filePath, const QString& exportHash, const QString& pdfPath);
    QString getExportCache(const QString& filePath, const QString& exportHash);
    bool hasValidExportCache(const QString& filePath, const QString& exportHash);
    void clearExportCache(const QString& filePath = QString());
    QString generateExportHash(const QString& settingsJson);
    QList<ExportCacheEntry> getExportCacheEntries() const;
    qint64 getExportCacheSize() const;
    void cleanupExportCache(int maxAgeDays = 7);
    
    // Manifest文件操作
    bool writeManifest(const QString& originalPath, int pageCount, const QDateTime& generatedAt,
                       const QString& engineVersion = QString(), const QString& extra = QString(),
                       double dpi = 0.0) const;

    // 检查缓存的DPI是否匹配
    bool isCacheDpiMatch(const QString& originalPath, double requiredDpi) const;

    // 缓存目录清理
    void cleanupEmptyDirectories() const;

    // === 空间监控机制 ===

    /**
     * 检查缓存目录的可用磁盘空间
     * @return 可用空间大小（字节）
     */
    qint64 getAvailableDiskSpace() const;

    /**
     * 检查缓存目录的可用磁盘空间（GB为单位）
     * @return 可用空间大小（GB）
     */
    double getAvailableDiskSpaceGB() const;

    /**
     * 检查是否有足够的磁盘空间
     * @param thresholdGB 空间阈值（GB）
     * @return 如果可用空间大于阈值返回true
     */
    bool hasEnoughDiskSpace(int thresholdGB) const;

    /**
     * 获取空间使用状态
     * @param thresholdGB 空间阈值（GB）
     * @return 空间状态描述字符串
     */
    QString getSpaceStatusText(int thresholdGB) const;

    /**
     * 启动空间监控
     * @param thresholdGB 空间阈值（GB）
     * @param checkIntervalMs 检查间隔（毫秒）
     */
    void startSpaceMonitoring(int thresholdGB, int checkIntervalMs = 60000);

    /**
     * 停止空间监控
     */
    void stopSpaceMonitoring();

signals:
    void cacheSizeChanged(qint64 newSize);
    void cacheEntryDeleted(const QString& hash);
    void allCacheDeleted();
    void cacheCleared();

    // 空间监控信号
    void diskSpaceLow(double availableGB, int thresholdGB);
    void diskSpaceWarning(const QString& message);
    void diskSpaceOk(double availableGB, int thresholdGB);

private:
    explicit UnifiedCacheManager(QObject *parent = nullptr);
    ~UnifiedCacheManager() override = default;
    
    // 禁用拷贝构造和赋值
    UnifiedCacheManager(const UnifiedCacheManager&) = delete;
    UnifiedCacheManager& operator=(const UnifiedCacheManager&) = delete;
    
    // 单例实例
    static UnifiedCacheManager* s_instance;
    static QMutex s_mutex;
    
    // 缓存目录路径
    mutable QString m_cacheDirectory;
    mutable bool m_cacheDirectoryInitialized;
    
    // 缓存配置
    qint64 m_maxCacheSize;     // 最大缓存大小（字节）
    int m_maxCacheAge;         // 最大缓存天数
    
    // 缓存项映射
    QHash<QString, CacheItem> m_cacheItems;
    mutable QMutex m_mutex;

    // 导出缓存管理
    QHash<QString, ExportCacheEntry> m_exportCache;
    mutable QString m_exportCacheDirectory;
    
    // 缓存大小缓存（避免频繁扫描）
    mutable qint64 m_cachedActualSize;
    mutable QDateTime m_lastSizeUpdate;
    static const int SIZE_CACHE_DURATION_SECONDS = 5; // 5秒内不重复扫描

    // 空间监控相关
    class QTimer* m_spaceMonitorTimer;
    int m_spaceThresholdGB;
    bool m_spaceMonitoringActive;
    bool m_lastSpaceCheckResult;        // 上次检查的结果，用于避免重复警告
    
    // 内部方法
    QString determineCacheDirectory() const;
    CacheEntry scanSingleCacheEntry(const QString& entryPath) const;
    qint64 calculateDirectorySize(const QString& dirPath) const;
    int countPageFiles(const QString& dirPath) const;
    QString readSourcePathFromManifest(const QString& dirPath) const;

    // 导出缓存内部方法
    QString getExportCacheDirectory() const;
    QString getExportCacheFilePath(const QString& filePath, const QString& exportHash) const;
    void loadExportCache();
    void saveExportCacheIndex();
    bool isExportCacheValid(const ExportCacheEntry& entry) const;
    
    // 缓存文件路径管理
    QString getCacheFilePath(const QString& cacheKey);
    void updateAccessInfo(const QString& cacheKey);
    void removeCacheItem(const QString& cacheKey);
    QList<QString> getLRUItems(int count = 10);

    // 空间监控内部方法
    void checkDiskSpace();
};

#endif // UNIFIEDCACHEMANAGER_H
